package edu.hawaii.myisern.action;


import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import org.junit.Test;

/**
 * Tests the collaboration form Action Bean.
 *
 * @author Kevin English
 */
public class TestCollaborationFormActionBean extends TestWeb {
  
  /** constants used in testing to appease PMD */
  private static final String EDIT_ADD_FORM_PAGE_TITLE = "ISERN - Edit/Add Collaboration";
  private static final String LIST_PAGE_TITLE = "ISERN - Collaborations";
  private static final String TEST_NAME = "Updated Collaboration name";
  private static final String NAME_FORM_FIELD = "collaboration.name";
  private static final String FORM_CSS_ID = "MyForm";
  private static final String TEST_COLLABORATION_NAME = "UM-UH-HPCS";
  private static final String EDIT_BUTTON = "preEdit";
  private static final String SAVE_BUTTON = "save";
  private static final String ADD_ORG_BUTTON = "addOrganization";
  private static final String REMOVE_ORG_BUTTON = "removeOrganization";
  private static final String REMOVE_BUTTON = "remove";
  private static final String JSP_TABLE_LIST = "collaborations.jsp";
  private static final String TEST_ENTITY_NAME = "Collaboration";
  private static final String NEW_LINK = "collaboration_form.jsp";
  private static final String TEST_NEW_NAME = "My New Collaboration II";
  private static final String EDIT_URL_QS_PREFIX = 
    "CollaborationForm.action?preEdit=&_sourcePage=%collaborations.jsp&id=";
  private static final String JSESSIONID = "JSESSIONID";

  /**
   * Tests that the form requires a name.
   *    
   * @throws Exception If problems occur
   */
  @Test
  public void testRequiresName() throws Exception {
    assertNotNull("this user session should not be null", 
        conversation.getCookieValue(JSESSIONID));
    WebResponse response = conversation.getResponse(getAppUrl() + "/" + JSP_TABLE_LIST);
    WebLink editLink = response.getLinkWith(TEST_COLLABORATION_NAME);
    response = editLink.click();
    WebForm form = response.getFormWithID(FORM_CSS_ID); 
    WebRequest request = form.getRequest(EDIT_BUTTON);
    response = conversation.getResponse(request);
    assertEquals("Check clicking edit link forwards to edit page.", 
        EDIT_ADD_FORM_PAGE_TITLE, response.getTitle());
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(SAVE_BUTTON);
    request.setParameter(NAME_FORM_FIELD, "");
    response = conversation.getResponse(request);
    assertEquals("Check that error message is displayed.", true, 
        response.getText().contains("Name is a required field"));    
    
  }
  /**
   *  Tests that a succssful save.
   *
   * @throws Exception If problems occur
   */
  @Test
  public void testSuccess() throws Exception {
    assertNotNull("the user session should not be null",
        conversation.getCookieValue(JSESSIONID) );
    WebResponse response = conversation.getResponse(getAppUrl() + "/" + JSP_TABLE_LIST);
    WebLink editLink = response.getLinkWith(TEST_COLLABORATION_NAME);
    response = editLink.click();
    WebForm form = response.getFormWithID(FORM_CSS_ID); 
    WebRequest request = form.getRequest(EDIT_BUTTON);
    response = conversation.getResponse(request);
    assertEquals("Check clicking edit forwards to proper page.", 
        EDIT_ADD_FORM_PAGE_TITLE, response.getTitle());
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(SAVE_BUTTON);
    //set new name
    String oldName = form.getParameterValue(NAME_FORM_FIELD);
    String newName = TEST_NAME;
    request.setParameter(NAME_FORM_FIELD, newName);
    response = conversation.getResponse(request);
    assertEquals("Check " + TEST_ENTITY_NAME + " name is updated.", true, 
        response.getText().contains(newName));   
    
    response = conversation.getResponse(getAppUrl() + "/" + EDIT_URL_QS_PREFIX + newName );
    form = response.getFormWithID(FORM_CSS_ID);
    request = form.getRequest(SAVE_BUTTON);
    request.setParameter(NAME_FORM_FIELD, oldName);

    response = conversation.getResponse(request);
    assertEquals("Check " + TEST_ENTITY_NAME + " name is updated.", true, 
        response.getText().contains(oldName));   
  }
  /**
   *  Tests a create.
   *  Create a collaboration, select an organization. assert both is done.
   *  Then remove the organization from the collaboration.
   * @throws Exception If problems occur
   */
  @Test
  public void testCreate() throws Exception {
    assertNotNull("the user session cannot not be null",
        conversation.getCookieValue("JSESSIONID") );
    WebResponse response = conversation.getResponse(getAppUrl() + "/" + NEW_LINK);
    assertEquals("Check clicking logout forwards to edit page.", 
        EDIT_ADD_FORM_PAGE_TITLE, response.getTitle());
    //add an organization
    WebForm form = response.getFormWithID(FORM_CSS_ID); 
    WebRequest request = form.getRequest(ADD_ORG_BUTTON);
    String org = request.getParameter("currentOrganization");
    response = conversation.getResponse(request);
    //type name
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(SAVE_BUTTON);
    request.setParameter(NAME_FORM_FIELD, TEST_NEW_NAME);
    response = conversation.getResponse(request);
    assertEquals("Check save forwards to lsit page.", LIST_PAGE_TITLE, response.getTitle());
    WebLink editLink = response.getLinkWith(TEST_NEW_NAME);
    assertNotNull("Check [" + TEST_NEW_NAME + "] name is added.", editLink);
    response = editLink.click();
    editLink = response.getLinkWith(org);
    assertNotNull("Check organization " + org + " is added.", editLink);
    //remove collaborating organization
    response = conversation.getResponse(getAppUrl() + "/" + JSP_TABLE_LIST);
    editLink = response.getLinkWith(TEST_NEW_NAME);
    response = editLink.click();
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(EDIT_BUTTON);
    response = conversation.getResponse(request);
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(REMOVE_ORG_BUTTON);
    response = conversation.getResponse(request);
    form = response.getFormWithID(FORM_CSS_ID); 
    request = form.getRequest(SAVE_BUTTON);
    response = conversation.getResponse(request);
    editLink = response.getLinkWith(TEST_NEW_NAME);
    response = editLink.click();
    editLink = response.getLinkWith(org);
    assertNotNull("Check organization " + org + " is removed.", editLink);
  }    
  
  /**
   * Test remove.
   * object should be gone after remove.
   * @throws Exception If problems occur
   */
  @Test
  public void testRemove() throws Exception {
    assertNotNull("the user session should not be null", 
        conversation.getCookieValue(JSESSIONID));
    WebResponse response = conversation.getResponse(getAppUrl() + "/" + JSP_TABLE_LIST);
    //remove collaboration
    response = conversation.getResponse(getAppUrl() + "/" + JSP_TABLE_LIST);
    WebLink editLink = response.getLinkWith(TEST_NEW_NAME);
    response = editLink.click();
    WebForm form = response.getFormWithID(FORM_CSS_ID); 
    WebRequest request = form.getRequest(REMOVE_BUTTON);
    response = conversation.getResponse(request);
    editLink = response.getLinkWith(TEST_NEW_NAME);
    assertNull("Check [" + TEST_NEW_NAME + "] should be gone.", editLink);
  }
}
